<html>
<head><meta charset="utf-8"><title>repr(C) structs and unions · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html">repr(C) structs and unions</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="152389146"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28C%29%20structs%20and%20unions/near/152389146" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bluss <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html#152389146">(Dec 22 2018 at 13:22)</a>:</h4>
<p>I would like to know and specify that the repr(C) layout rules apply, even if we use non-C compatible types in the struct or union fields.</p>
<p>Given <code>#[repr(C)] union Foo&lt;T&gt; { empty: (), value: ManuallyDrop&lt;T&gt; }</code> one can say that the types <code>Foo&lt;String&gt;</code> or <code>Foo&lt;Rc&lt;dyn std::fmt::Display&gt;&gt;</code> are not meaningfully C compatible, yet it would be important to know that representation rules for offset from the start of the type and field order still apply. I assume they do, but I think it has not been clear what "C-compatible" means when faced with blatant c-incompatibility.</p>
<p>Same question with <code>#[repr(C)] struct Bar&lt;T: ?Sized&gt; { value: T }</code> and the type <code>Bar&lt;str&gt;</code>.</p>
<p>Edit: Even type <code>()</code> in itself is also incompatible, strictly speaking.</p>



<a name="152389967"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28C%29%20structs%20and%20unions/near/152389967" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html#152389967">(Dec 22 2018 at 13:48)</a>:</h4>
<p><span class="user-mention" data-user-id="139363">@bluss</span>  <code>repr(C)</code> does not apply recursively / transitively to the types of the struct / union fields</p>



<a name="152389994"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28C%29%20structs%20and%20unions/near/152389994" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html#152389994">(Dec 22 2018 at 13:49)</a>:</h4>
<p>it only applies to the layout of the struct that's actually repr(C), the layout of the fields is irrelevant</p>



<a name="152390045"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28C%29%20structs%20and%20unions/near/152390045" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html#152390045">(Dec 22 2018 at 13:50)</a>:</h4>
<p>e.g. given <code>struct Foo;</code> and <code>#[repr(C)] struct Bar(Foo);</code> we have to be able to write to both <code>Bar</code>'s field 0 and <code>Foo</code>s via a <code>&amp;mut Foo</code> without knowing where the <code>&amp;mut Foo</code> actually points to (a single <code>Foo</code>, or a <code>Foo</code> inside a <code>Bar</code>).</p>



<a name="152390340"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28C%29%20structs%20and%20unions/near/152390340" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bluss <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html#152390340">(Dec 22 2018 at 14:00)</a>:</h4>
<p>Sure, there is no question about being recursive. Existing recommendations seem to be written in terms of guaranteeing compatibility with an equivalent struct in C. My question is, can we also use the guarantees of repr(C) layout even when there can be no equivalent C struct.</p>



<a name="152392246"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28C%29%20structs%20and%20unions/near/152392246" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html#152392246">(Dec 22 2018 at 15:05)</a>:</h4>
<p>per <a href="https://github.com/rust-rfcs/unsafe-code-guidelines/blob/master/reference/src/representation/unions.md" target="_blank" title="https://github.com/rust-rfcs/unsafe-code-guidelines/blob/master/reference/src/representation/unions.md">https://github.com/rust-rfcs/unsafe-code-guidelines/blob/master/reference/src/representation/unions.md</a>, the offset of all fields in a <code>repr(C)</code> union is 0</p>



<a name="152396429"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28C%29%20structs%20and%20unions/near/152396429" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html#152396429">(Dec 22 2018 at 17:22)</a>:</h4>
<p>that's independent from whatever we'll end up doing with ZSTs in <code>repr(C)</code> types</p>



<a name="152398779"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28C%29%20structs%20and%20unions/near/152398779" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bluss <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html#152398779">(Dec 22 2018 at 18:47)</a>:</h4>
<p>Great, so there is no implied restriction to certain C-compatible types and we apply the layout rule to all unions/structs.</p>



<a name="152404185"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr%28C%29%20structs%20and%20unions/near/152404185" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/repr(C).20structs.20and.20unions.html#152404185">(Dec 22 2018 at 22:03)</a>:</h4>
<p>Exactly, in particular, <code>repr(C)</code> is orthogonal to whether a type is "C FFI safe"/"proper ctype" etc.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>